/*
MIT License

Copyright (c) 2021 МГТУ им. Н.Э. Баумана, кафедра ИУ-6, Михаил Фетисов,

https://bmstu.codes/lsx/simodo
*/

#ifndef simodo_conversion_functions
#define simodo_conversion_functions

/*! \file conversion_functions.h
    \brief Функции преобразования UNICODE UTF8 и UTF16
*/

#include <string>

#ifdef CROSS_WIN
#define SIMODO_INOUT_STD_STRING(string) (simodo::inout::fromUtf8CharToWChar(string).c_str())
#define SIMODO_INOUT_STD_IFSTREAM(stream, string) \
std::ifstream stream(simodo::inout::fromUtf8CharToWChar(string).c_str())
#define SIMODO_INOUT_STD_IFSTREAM_IOS(stream, string, ios) \
std::ifstream stream(simodo::inout::fromUtf8CharToWChar(string).c_str(), (ios))
#else
#define SIMODO_INOUT_STD_STRING(string) (string)
#define SIMODO_INOUT_STD_IFSTREAM(stream, string) \
std::ifstream stream(string)
#define SIMODO_INOUT_STD_IFSTREAM_IOS(stream, string, ios) \
std::ifstream stream((string), (ios))
#endif

namespace simodo::inout
{
#ifdef CROSS_WIN
    /*!
     * \brief Функция переводит строку UTF-8 в wchar_t
     * \param str     Строка UTF-8
     * \return        Строка wchar_t
     */
    std::wstring fromUtf8CharToWChar(const std::string & str);

    /*!
     * \brief Функция переводит строку wchar_t в UTF-8
     * \param str     Строка wchar_t
     * \return        Строка UTF-8
     */
    std::string fromWCharToUtf8Char(const std::wstring & str);
#endif

    /*!
     * \brief Функция переводит строку UTF-8 в UTF-16
     * \param str     Строка UTF-8
     * \return        Строка UTF-16
     */
    std::u16string toU16(const std::string & str);

    /*!
     * \brief Функция переводит строку UTF-16 в UTF-8
     * \param str     Строка UTF-16
     * \return        Строка UTF-8
     */
    std::string toU8(const std::u16string & str);

    /*!
     * \brief Удаление лишних нулей в дробной части
     * \param s Строковое представление числа
     * \return Строковое представление числа с удаленными нулями в конце дробной части
     */
    std::string clearNumberFractionalPart(std::string s);

    /**
     * @brief Заменяет в исходной строке str все подстроки from на подстроки to.
     * 
     * @param str исходная строка
     * @param from подстрока, которую нужно заменить
     * @param to подстрока, которая заменяет
     */
    void replaceAll(std::u16string &str, const std::u16string &from, const std::u16string &to);

    /**
     * @brief Заменяет в исходной строке str все подстроки from на подстроки to.
     * 
     * Функция оптимизирована для работы с большими строками, в которых заведомо есть 
     * искомые значения, т.к. делает по крайней мере одно копирование.
     * 
     * @param str исходная строка
     * @param from подстрока, которую нужно заменить
     * @param to подстрока, которая заменяет
     */
    std::u16string replace(const std::u16string &str, const std::u16string &from, const std::u16string &to);

    /**
     * @brief Кодирует ESC-последовательности для передачи через текстовые протоколы.
     * 
     * Шифруются символы новой строки \n (для передачи через HTTP и для предотвращения разрывов
     * строк в JSON) и двойной кавычки (для использования внутри строковых констант JSON).
     * 
     * @param text исходный текст
     * @return текст с закодированными последовательностями.
     */
    std::u16string encodeSpecialChars(const std::u16string & text);

    /**
     * @brief Декодирует ESC-последовательности после кодирования с использованием
     * encodeSpecialChars.
     * 
     * @param text исходный текст
     * @return текст с декодированными последовательностями.
     */
    std::u16string decodeSpecialChars(const std::u16string & text);

    /**
     * @brief Заменяет в исходной строке str все подстроки from на подстроки to
     * 
     * @param str исходная строка
     * @param from подстрока, которую нужно заменить
     * @param to подстрока, которая заменяет
     */
    void replaceAll(std::string &str, const std::string &from, const std::string &to);

    /**
     * @brief Кодирует ESC-последовательности для передачи через текстовые протоколы.
     * 
     * Шифруются символы новой строки \n (для передачи через HTTP и для предотвращения разрывов
     * строк в JSON) и двойной кавычки (для использования внутри строковых констант JSON).
     * 
     * @param text исходный текст
     * @return текст с закодированными последовательностями.
     */
    std::string encodeSpecialChars(const std::string & text);

    /**
     * @brief Декодирует ESC-последовательности после кодирования с использованием
     * encodeSpecialChars.
     * 
     * @param text исходный текст
     * @return текст с декодированными последовательностями.
     */
    std::string decodeSpecialChars(const std::string & text);

}

#endif // simodo_conversion_functions
